/*!
 * \file SelStrategyMgr.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 *
 * \brief SEL策略管理器头文件
 * 
 * 本文件定义了SEL(Selection)策略管理器类，负责SEL策略工厂的加载、
 * 策略实例的创建和管理。支持动态加载策略工厂DLL/SO文件，创建和管理策略实例的生命周期。
 * SEL策略主要用于选股、组合管理等场景。
 */
#pragma once
#include <memory>
#include <boost/core/noncopyable.hpp>

#include "../Includes/FasterDefs.h"
#include "../Includes/SelStrategyDefs.h"

#include "../Share/DLLHelper.hpp"

/**
 * @class SelStraWrapper
 * @brief SEL策略包装器类
 * 
 * 用于包装SEL策略实例，管理策略的生命周期，确保策略对象的正确创建和销毁。
 * 采用RAII模式，在析构时自动释放策略资源。
 */
class SelStraWrapper
{
public:
	/**
	 * @brief 构造函数
	 * 
	 * @param stra SEL策略实例指针
	 * @param fact SEL策略工厂指针
	 */
	SelStraWrapper(SelStrategy* stra, ISelStrategyFact* fact) :_stra(stra), _fact(fact){}
	
	/**
	 * @brief 析构函数
	 * 
	 * 自动释放策略实例资源
	 */
	~SelStraWrapper()
	{
		if (_stra)
		{
			_fact->deleteStrategy(_stra);
		}
	}

	/**
	 * @brief 获取策略实例
	 * 
	 * @return SEL策略实例指针
	 */
	SelStrategy* self(){ return _stra; }

private:
	SelStrategy*		_stra;	/**< SEL策略实例指针 */
	ISelStrategyFact*	_fact;	/**< SEL策略工厂指针 */
};

/**< SEL策略智能指针类型定义 */
typedef std::shared_ptr<SelStraWrapper>	SelStrategyPtr;

/**
 * @class SelStrategyMgr
 * @brief SEL策略管理器类
 * 
 * 负责管理SEL策略工厂和策略实例，提供策略的动态加载、创建和管理功能。
 * 
 * 主要功能包括：
 * - 动态加载SEL策略工厂DLL/SO文件
 * - 创建和管理SEL策略实例
 * - 策略实例的查找和获取
 * - 策略工厂的生命周期管理
 * 
 * @note SEL策略专门用于选股和组合管理场景
 * @see SelStraWrapper, ISelStrategyFact
 */
class SelStrategyMgr : private boost::noncopyable
{
public:
	/**
	 * @brief 构造函数
	 */
	SelStrategyMgr();
	
	/**
	 * @brief 析构函数
	 */
	~SelStrategyMgr();

public:
	/**
	 * @brief 加载策略工厂
	 * 
	 * 从指定路径加载所有的SEL策略工厂DLL/SO文件
	 * 
	 * @param path 策略工厂文件所在目录路径
	 * @return 加载成功返回true，失败返回false
	 */
	bool loadFactories(const char* path);

	/**
	 * @brief 创建策略实例（通过策略名称）
	 * 
	 * 根据策略名称创建策略实例，策略名称格式为"工厂名.策略名"
	 * 
	 * @param name 策略名称，格式为"factname.unitname"
	 * @param id 策略实例ID
	 * @return 策略实例智能指针，失败返回空指针
	 */
	SelStrategyPtr createStrategy(const char* name, const char* id);
	
	/**
	 * @brief 创建策略实例（通过工厂名和策略名）
	 * 
	 * 根据指定的工厂名和策略名创建策略实例
	 * 
	 * @param factname 策略工厂名称
	 * @param unitname 策略单元名称
	 * @param id 策略实例ID
	 * @return 策略实例智能指针，失败返回空指针
	 */
	SelStrategyPtr createStrategy(const char* factname, const char* unitname, const char* id);

	/**
	 * @brief 获取策略实例
	 * 
	 * 根据策略ID获取已创建的策略实例
	 * 
	 * @param id 策略实例ID
	 * @return 策略实例智能指针，不存在返回空指针
	 */
	SelStrategyPtr getStrategy(const char* id);
	
private:
	/**
	 * @struct _StraFactInfo
	 * @brief SEL策略工厂信息结构体
	 * 
	 * 存储SEL策略工厂的详细信息，包括模块路径、句柄、工厂实例等
	 */
	typedef struct _StraFactInfo
	{
		std::string			_module_path;	/**< 模块文件路径 */
		DllHandle			_module_inst;	/**< 模块句柄 */
		ISelStrategyFact*	_fact;		/**< SEL策略工厂实例 */
		FuncCreateSelStraFact	_creator;	/**< 创建工厂函数指针 */
		FuncDeleteSelStraFact	_remover;	/**< 删除工厂函数指针 */
	} StraFactInfo;
	
	/**< SEL策略工厂映射表类型定义 */
	typedef faster_hashmap<LongKey, StraFactInfo> StraFactMap;
	
	/**< SEL策略工厂映射表 */
	StraFactMap	_factories;

	/**< SEL策略实例映射表类型定义 */
	typedef faster_hashmap<LongKey, SelStrategyPtr> StrategyMap;
	
	/**< SEL策略实例映射表 */
	StrategyMap	_strategies;
};

